package com.lanxiao.cloud.gateway.filter;

import com.lanxiao.cloud.common.core.constant.LanXiaoConstant;
import com.lanxiao.cloud.common.core.error.OauthErrorType;
import com.lanxiao.cloud.common.core.exception.BusinessException;
import com.lanxiao.cloud.oauth.api.OauthDubboApi;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

/**
 * @author ：qiaoliang
 * @date ：2021-09-09
 */
@Component
public class TokenGatewayFilter implements GlobalFilter {

  private static final Logger log = LoggerFactory.getLogger(TokenGatewayFilter.class);

  @Value("${filter.urls}")
  private String filterUrls;

  @DubboReference
  private OauthDubboApi oauthDubboApi;

  private boolean filterUrls(String path) {
    if(StringUtils.isNotEmpty(filterUrls)){
      final String[] urls = filterUrls.split(",");
      for (String url : urls) {
        if(StringUtils.endsWithIgnoreCase(path, url)){
          return Boolean.FALSE;
        }
      }
    }
    return Boolean.TRUE;
  }

  @Override
  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    ServerHttpRequest request = exchange.getRequest();
    final String path = request.getPath().value();
    final String method = request.getMethodValue();
    final String ip = request.getHeaders().getFirst(LanXiaoConstant.X_IP);
    final String cityName = request.getHeaders().getFirst(LanXiaoConstant.X_CITY_NAME);
    log.info("请求地址：{}，请求模式：{}，请求IP：{}，请求城市：{}", path, method, ip, cityName);
    if(this.filterUrls(path)) {

      final String auth = request.getHeaders().getFirst(LanXiaoConstant.AUTHORIZATION);
      final Long userId = oauthDubboApi.checkToken(auth);
      oauthDubboApi.checkUserPermission(userId, path, method);

      request.mutate().header(LanXiaoConstant.X_IP, ip).build();
      request.mutate().header(LanXiaoConstant.X_CITY_NAME, cityName).build();
      request.mutate().header(LanXiaoConstant.X_CURRENT_ID, String.valueOf(userId)).build();
      return chain.filter(exchange.mutate().request(request).build());
    }
    return chain.filter(exchange);
  }
}
